using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;
using System;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Services.Database
{
    /// <summary>
    /// 延迟数据库上下文工厂实现
    /// 在首次使用时才创建真实的数据库连接，优化启动性能
    /// </summary>
    public class LazyDbContextFactory : ILazyDbContextFactory, IDisposable
    {
        private readonly IConfiguration _configuration;
        private readonly ILogger<LazyDbContextFactory> _logger;
        private LowCodeDbContext? _cachedContext;
        private bool _initialized = false;
        private readonly object _lock = new object();

        public LazyDbContextFactory(
            IConfiguration configuration,
            ILogger<LazyDbContextFactory> logger)
        {
            _configuration = configuration;
            _logger = logger;
        }

        /// <summary>
        /// 创建数据库上下文（延迟初始化）
        /// </summary>
        public LowCodeDbContext CreateDbContext()
        {
            if (_cachedContext != null)
            {
                return _cachedContext;
            }

            lock (_lock)
            {
                if (_cachedContext != null)
                {
                    return _cachedContext;
                }

                try
                {
                    var startTime = DateTime.UtcNow;
                    _logger.LogInformation("[LazyDb] 开始初始化延迟数据库连接...");

                    // 获取数据库配置
                    var mapper = new AppSettingsMapper(_configuration);
                    var databaseConfig = mapper.Bind<JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Models.DatabaseConfiguration>("");
                    
                    var dbType = databaseConfig.DatabaseType ?? "Postgres"; // 默认PostgreSQL
                    var connStr = UnifiedConfigurationProcessor.GetDatabaseConnectionString(dbType);

                    // 创建数据库选项
                    var optionsBuilder = new DbContextOptionsBuilder<LowCodeDbContext>();
                    
                    // 根据数据库类型配置 - 仅支持生产级数据库
                    switch (dbType.ToLower())
                    {
                        case "postgres":
                        case "postgresql":
                            optionsBuilder.UseNpgsql(connStr);
                            break;
                        case "sqlserver":
                            optionsBuilder.UseSqlServer(connStr);
                            break;
                        case "mysql":
                            optionsBuilder.UseMySql(connStr, ServerVersion.AutoDetect(connStr));
                            break;
                        default:
                            throw new NotSupportedException($"不支持的数据库类型: {dbType}。仅支持 PostgreSQL、SQL Server、MySQL。");
                    }

                    // 性能优化配置
                    optionsBuilder.EnableServiceProviderCaching(true);
                    optionsBuilder.EnableSensitiveDataLogging(false);

                    _cachedContext = new LowCodeDbContext(optionsBuilder.Options);
                    _initialized = true;

                    var elapsed = (DateTime.UtcNow - startTime).TotalMilliseconds;
                    _logger.LogInformation("[LazyDb] 数据库连接初始化完成，类型: {DbType}, 耗时: {Elapsed}ms", 
                        dbType, elapsed);

                    return _cachedContext;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "[LazyDb] 数据库连接初始化失败: {Message}", ex.Message);
                    
                    // 生产环境：明确失败，不进行误导性降级
                    throw new InvalidOperationException($"数据库连接失败，无法启动应用程序。错误详情: {ex.Message}", ex);
                }
            }
        }

        /// <summary>
        /// 检查数据库是否可用
        /// </summary>
        public bool IsDbAvailable()
        {
            try
            {
                if (_cachedContext == null)
                {
                    return false; // 未初始化，假设可用
                }

                return _cachedContext.Database.CanConnect();
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "[LazyDb] 数据库可用性检查失败");
                return false;
            }
        }

        /// <summary>
        /// 获取数据库连接状态
        /// </summary>
        public string GetConnectionStatus()
        {
            if (!_initialized)
            {
                return "未初始化 (延迟加载)";
            }

            if (_cachedContext == null)
            {
                return "连接失败";
            }

            try
            {
                var canConnect = _cachedContext.Database.CanConnect();
                var connectionString = _cachedContext.Database.GetConnectionString();
                var providerName = _cachedContext.Database.ProviderName;
                
                return $"状态: {(canConnect ? "已连接" : "断开")}, 提供程序: {providerName}";
            }
            catch (Exception ex)
            {
                return $"检查失败: {ex.Message}";
            }
        }

        public void Dispose()
        {
            lock (_lock)
            {
                _cachedContext?.Dispose();
                _cachedContext = null;
                _initialized = false;
            }
        }
    }
}
